#include <string.h>
#include <event2/bufferevent.h>
#include <event2/event.h>
#include <string>
#include "ftp_task_cmd.h"
#include "../util/common_util.h"

#define BUFS 4096

void FtpTaskCmd::Reg(std::string cmd, FtpTaskBase *call) {
	LOGDEBUG("At FtpTaskCmd::Reg");
	if (!call) {
		std::cout << "FtpTaskCmd::Reg call is null " << std::endl;
		return;
	}
	if (cmd.empty()) {
		std::cout << "FtpTaskCmd::Reg cmd is null " << std::endl;
		return;
	}
	// 已经注册的是否覆盖，不覆盖，提示错误
	if (calls.find(cmd) != calls.end()) {
		std::cout << cmd << " is alredy register" << std::endl;
		return;
	}
	LOGDEBUG(cmd << " Reg success");
	call->base = base;
	call->cmdTask = this;
	calls[cmd] = call;
	calls_del[call] = 0;
}

void FtpTaskCmd::Event(bufferevent *bev, short events) {
	LOGDEBUG("At FtpTaskCmd::Event");
	if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR | BEV_EVENT_TIMEOUT)) {
		delete this;
	}
}

void FtpTaskCmd::Read(bufferevent *bev) {
	std::cout << std::endl;
	LOGDEBUG("At FtpTaskCmd::Read");
	char buf[BUFS] = { 0 };
	while (1) {
		int len = bufferevent_read(bev, buf, BUFS);
		if (len <= 0) break;
		std::cout << "Recv CMD(" << len << "):" << buf;
		// 分发到处理对象
		// 分析出类型
		std::string type = "";
		for (int i = 0; i < len; i++) {
			if (buf[i] == ' ' || buf[i] == '\r')
				break;
			type += buf[i];
		}

		// 解析命令类型并调用命令对象进行解析
		std::cout << "type is [" << type << "]" << std::endl;
		if (calls.find(type) != calls.end()) {
			LOGDEBUG("begin to parse");
			FtpTaskBase *t = calls[type];
			t->Parse(type, buf);
			LOGDEBUG("curDir: [" << curDir << "]");
		}
		else {
			std::cout << "parse object not found" << std::endl;
			ResCMD("200 OK\r\n");
		}
	}
}

bool FtpTaskCmd::Init() {
	LOGDEBUG("At FtpTaskCmd::Init");

	// 在线程的base里添加一个缓冲区对sock的缓冲事件，这就是命令通道
	bufferevent *bev = bufferevent_socket_new(base, sock, BEV_OPT_CLOSE_ON_FREE);
	if (!bev) {
		delete this;
		return false;
	}

	// 添加超时
	timeval t = {300, 0};
	bufferevent_set_timeouts(bev, &t, 0);

	std::string msg = "220 Welcome to XFtpServer\r\n";
	bufferevent_write(bev, msg.c_str(), msg.size());

	this->cmdTask = this;
	this->bev = bev;
	// 注册本对象实现的回调函数
	Setcb(bev);

	return true;
}

FtpTaskCmd::FtpTaskCmd() {
}

FtpTaskCmd::~FtpTaskCmd() {
	ClosePORT();
	for (auto i : calls_del) {
		delete i.first;
	}
}
